﻿using SUNRPA.CONTROLS.IMPL.domain;
using SUNRPA.CONTROLS.IMPL.domain.constant;
using SUNRPA.CONTROLS.IMPL.domain.flowItemParam;
using SUNRPA.CONTROLS.IMPL.domain.flowRunningVar;
using SUNRPA.CONTROLS.IMPL.util;
using System.Collections;
using System.Collections.Concurrent;

namespace SUNRPA.CONTROLS.IMPL.controls {
    public class IFNAction:BaseControlActions {
        public override int Execute(int currentIndex, FlowItem item, ConcurrentDictionary<string, ConcurrentDictionary<string, RPAVariableDefineWrapper>> globleData, List<FlowItem> flowItems) {
            IFNParam? param = item.ControlParam as IFNParam;
            int conRelation = param.ConRelation;
            List<IFCondition> conditions = param.Conditions;
            bool conditionResult;
            if(conRelation == 0) { 
                //与
                bool resultTemp = true;
                foreach(IFCondition con in conditions) { 
                    resultTemp = resultTemp & con.GetConResult(globleData);
                    if(!resultTemp) { 
                        break;
                    }
                }
                conditionResult = resultTemp;
            } else { 
                //或
                bool resultTemp = false;
                foreach(IFCondition con in conditions) { 
                    resultTemp = resultTemp | con.GetConResult(globleData);
                    if(resultTemp) {
                        break;
                    }
                }
                conditionResult = resultTemp;
            }
            //将if esleif else 索引分段
            //由于esleif和else肯定是存在于if中的所以不用考虑单独情况
            //一个if只有一个else多个elseif
            //else不能再elseif前面
            List<int> elseIfIndexs = new List<int>();
            int elseIndex = -1;
            for(int j = currentIndex + 1; j < item.EndTag.Index; j++) {
                FlowItem fi = flowItems[j];
                //如果包含另一个IF则直接跳过
                if(fi.ControlKey.Equals("IFN")) { 
                    j = fi.EndTag.Index;
                    continue;
                }
                if(fi.ControlKey.Equals("ElseN")) {
                    if(elseIndex != -1) { 
                        throw new RpaRuntimeException("IF条件内只能存在一个Else");
                    }
                    elseIndex = fi.Index;
                }

                if(fi.ControlKey.Equals("ElseIFN")) { 
                    if(elseIndex != -1) { 
                        throw new RpaRuntimeException("Else必须再ElseIF之后");
                    }
                    elseIfIndexs.Add(fi.Index);
                }
            }

            //经过以上校验，if中必定是按照if-elseif-elseif-。。。-else顺序的流程
            int ifendIndex = item.EndTag.Index;
            if(elseIfIndexs.Count > 0) {
                ifendIndex = elseIfIndexs[0];
                elseIfIndexs.RemoveAt(0);
            }else if(elseIndex != -1) { 
                ifendIndex = elseIndex;
            }
            if(conditionResult) { 
                for(int j = currentIndex + 1; j < ifendIndex; j++) {
                    BaseControlActions.updateInfoDelegate(j);
                    j = ExecuteAction(flowItems[j], globleData, flowItems);
                    
                }
            } else { 
                //不是else就是elseif
                for(int j = ifendIndex; j < item.EndTag.Index; j++) {
                    FlowItem middleItem = flowItems[j];
                    FlowItem tempEndItem = new FlowItem();
                    FlowItem trueEndItem = new FlowItem();
                    middleItem.EndTag = tempEndItem;
                    tempEndItem.Index = item.EndTag.Index;
                    trueEndItem.Index = item.EndTag.Index;
                    tempEndItem.EndTag = trueEndItem;
                    if(elseIfIndexs.Count > 0) {
                        tempEndItem.Index = elseIfIndexs[0];
                        elseIfIndexs.RemoveAt(0);
                    }else if(elseIndex != -1) {
                        if(middleItem.Index == elseIndex) { 
                            tempEndItem.Index = item.EndTag.Index;
                        } else { 
                            tempEndItem.Index = elseIndex;
                        }
                    }
                    BaseControlActions.updateInfoDelegate(j);
                    j = ExecuteAction(middleItem, globleData, flowItems);
                }
            }
            return item.EndTag.Index;
        }
    }
}
